<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="ColorFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    //uniform float u_Fadian;
    uniform vec4 u_Color;
    uniform vec2 u_CanvasPosi;
    void main(){
        gl_FragColor = vec4(
            (gl_FragCoord.x / u_CanvasPosi.x),
            (gl_FragCoord.y / u_CanvasPosi.y),
            1,
            1);
    }
</script>
<script id="TextureVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec2 a_Pin;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying vec2 v_Pin;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
        v_Pin = a_Pin;
    }
</script>
<script id="TextureFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    varying vec2 v_Pin;
    void main(){
        vec4 a = texture2D(u_Sampler, v_Pin);
        if(a.r <= 0.2){
            a = vec4(0,0,0,0);
        }
        gl_FragColor = a;
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly3.js'

    import Geo from '../js/Poly/Geo.js'
    import Mat from '../js/Poly/Mat.js'
    import Obj3D from '../js/Poly/Obj3D.js'
    import Scene from '../js/Poly/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl", { antialias: true, });
    //开始背景遮挡//会频闪
    // gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
    //#endregion



    const scene = new Scene({ gl: gl });



    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();

    const colorArr = [];

    const camera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const cameraController = new CameraController({
        camera: camera,
        canvas: canvas,
        rendEvent: draw,
        pvMatrix: pvM4,
        MoveEvent: false,
        RotateEvent: false,
        ScaleEvent: false,
    });

    let img = new Image();
    img.src = './Image/钉钉.png';
    img.onload = function () {

        for (let i = 0; i < 30; i++) {
            createColorObj(getPositionArr([0.1, 0.1, 0]), 1, [Math.random(), Math.random(), 0.5, 1]);
        }

        draw();
    }

    let index = 0;
    canvas.addEventListener('wheel', ({ deltaY }) => {
        if (deltaY > 0) {
            index++;
        } else {
            index--
        }
        if (index < 0) {
            index = 0;
        }
        if (index > 15) {
            index = 15;
        }

        //边缘方块
        if (0 <= index && index <= 5) {
            addAnim({
                id: 0,
                state: 0,
                ctime: 100,
                from: modelM4.elements[14],
                to: index,
                action: (num) => {
                    modelM4.copy(new Matrix4().multiply(new Matrix4().setPosition(0, 0, num)));
                }
            });
        }

        draw();
    });


    function createColorObj(nodes, fadian, color) {
        let program = CreateProgram(gl,
            document.querySelector('#ColorVertexShader').innerText,
            document.querySelector('#ColorFragmentShader').innerText);
        let obj = new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': {
                        size: 3, array: new Float32Array(nodes)
                    },
                },
                element: {
                    array: new Uint8Array([0, 1, 2, 0, 2, 3])
                }
            }),
            mat: new Mat({
                program: program,
                mode: ['TRIANGLES'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                    'u_Fadian': { type: 'uniform1f', value: fadian },
                    'u_Color': { type: 'uniform4fv', value: color },
                    'u_CanvasPosi': { type: 'uniform2fv', value: [canvas.width, canvas.height] }
                },
            }),
        });
        colorArr.push(obj)
        scene.add(obj);
    }

    function getPositionArr([w, h, z]) {
        let node = [
            -w, h, z,
            -w, -h, z,
            w, -h, z,
            w, h, z
        ];
        let rX = Math.random();
        let rY = 1.2 - rX;
        rX *= (Math.random() * 10 % 2 > 1 ? -1 : 1);
        rY *= (Math.random() * 10 % 2 > 1 ? -1 : 1);
        let rZ = Math.random() * -3;
        //随机位置生成
        for (let i = 0; i < node.length; i += 3) {
            var v = new Vector3(node[i], node[i + 1], node[i + 2])
            v.applyMatrix4(new Matrix4().setPosition(rX, rY, rZ));
            node[i] = v.x;
            node[i + 1] = v.y;
            node[i + 2] = v.z;
        }
        return node;
    }

    //渲染
    function draw() {
        scene.setUniform('u_ModelM4', { value: modelM4.elements });
        scene.draw();
    }

    const animArr = [];
    //{ 
    //      id : 0,* //标识ID
    //      state : 0,* //0表示未开始(刚加入),1表示正在进行,2表示已经结束
    //      ctime : 1000,* //持续时间
    //      from : 0,* //从
    //      to : 0,* //到
    //      action : null,*// 调用函数
    //      beginTime : 0, //开始时间
    //}
    (function ani(time) {

        for (let i = 0; i < animArr.length; i++) {
            const { to, from, action, ctime } = animArr[i];
            if (animArr[i].state == 0) {

                animArr[i].state = 1;
                animArr[i].beginTime = time;
            }
            if (animArr[i].state == 1) {
                //正在执行
                if (time - animArr[i].beginTime > ctime) {
                    animArr[i].state = 2;
                } else {
                    let a = (time - animArr[i].beginTime) / ctime;//百分比进度
                    let cur = (to - from) * a + from;//当前值
                    action(cur);
                }
            } else {
                console.log('动画[' + animArr[i].id + ']执行完成')
                // console.log(modelM4.elements[14], from, to)
                animArr.splice(i, 1);
            }
            draw();
        }



        requestAnimationFrame(ani);
    })();


    function addAnim(data) {
        for (let i = 0; i < animArr.length; i++) {
            if (animArr[i].id == data.id) {
                animArr[i].to = data.to;
                animArr[i].from = data.from;
                animArr[i].state = 0;
                return;
            }
        }
        data.state = 0;
        animArr.push(data);
    }

</script>

</html>